package mate_preference

import (
	"context"
	"errors"
	"fmt"

	commonTools "algo-sdk-go/common/tools"
	"algo-sdk-go/project/matchmaking/application/command"
	"algo-sdk-go/project/matchmaking/common/biz_tools"
	"algo-sdk-go/project/matchmaking/common/constant"
	"algo-sdk-go/project/matchmaking/domain/models/valueobject"
	"algo-sdk-go/project/matchmaking/domain/port/repo/ops"
	"algo-sdk-go/project/matchmaking/matchMaking-api/internal/svc"
	"algo-sdk-go/project/matchmaking/matchMaking-api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

var (
	AddressCast = func(t types.Address) valueobject.Address {
		return valueobject.Address{
			Province: t.Province,
			City:     t.City,
			District: t.District,
			FullName: t.FullName,
		}
	}

	AddressDeCast = func(t valueobject.Address) types.Address {
		return types.Address{
			Province: t.Province,
			City:     t.City,
			District: t.District,
			FullName: t.FullName,
		}
	}

	DecodeAddress = func(addr valueobject.Address) string {
		return fmt.Sprintf("%s-%s-%s", addr.Province, addr.City, addr.District)
	}
)

type SyncMatePreferenceLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewSyncMatePreferenceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SyncMatePreferenceLogic {
	return &SyncMatePreferenceLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SyncMatePreferenceLogic) SyncMatePreference(req *types.SyncMatePreferenceRequest) (resp *types.SyncMatePreferenceResponse, err error) {
	syncReason, err := l.svcCtx.MatePreferenceService.BatchAddMatePreference(l.ctx, []command.MatePreferenceCommand{transMatePreferenceCommand(req.MatePreference)})
	if err != nil {
		return nil, err
	}

	if len(syncReason.FailedList) != 0 {
		return nil, errors.New(syncReason.FailedList[0].Reason)
	}

	if len(syncReason.SuccessList) == 0 {
		return nil, errors.New("更新失败")
	}

	resp = &types.SyncMatePreferenceResponse{
		Data: types.SyncMatePreferenceData{
			UserNum: syncReason.SuccessList[0],
		},
	}
	return
}

func transMatePreferenceCommand(req types.MatePreference) command.MatePreferenceCommand {
	minAge := req.AgeRange.MinAge
	maxAge := req.AgeRange.MaxAge
	if req.AgeRange.MinBrithday != "" {
		minAge, _ = biz_tools.ParseAge(req.AgeRange.MinBrithday)
	}
	if req.AgeRange.MaxBrithday != "" {
		maxAge, _ = biz_tools.ParseAge(req.AgeRange.MaxBrithday)
	}

	return command.MatePreferenceCommand{
		UserNum:   req.UserNum,
		Standards: "",
		HeightRange: ops.HeightRange{
			MinHeight: req.HeightRange.MinHeight,
			MaxHeight: req.HeightRange.MaxHeight,
		},
		WeightRange: ops.WeightRange{
			MinWeight: req.WeightRange.MinWeight,
			MaxWeight: req.WeightRange.MaxWeight,
		},
		AgeRange: ops.AgeRange{
			MinAge: minAge,
			MaxAge: maxAge,
		},
		IncomeRange: ops.IncomeRange{
			MinIncome: req.IncomeRange.MinIncome,
			MaxIncome: req.IncomeRange.MaxIncome,
		},
		EducationRange: ops.EducationRange{
			MinEducation: constant.Education(req.EducationRange.MinEducation),
			MaxEducation: constant.Education(req.EducationRange.MaxEducation),
		},
		OccupationPreference: commonTools.Cast(req.OccupationRequire, func(t string) constant.Occupation {
			return constant.Occupation(t)
		}),
		HometownPreference:         commonTools.Cast(req.HometownRequired, AddressCast),
		CurrentResidencePreference: commonTools.Cast(req.CurrentResidenceRequired, AddressCast),
		PersonalityTraits:          req.PersonalityTraits,
		OtherRequired:              req.OtherRequired,
		CreateUser:                 req.CreateUser,
		ModifyUser:                 req.ModifyUser,
	}
}
